package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"strconv"
	"time"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/widget"
	"github.com/go-vgo/robotgo"
)

type StepParameters struct {
	X      *int    `json:"x,omitempty"`
	Y      *int    `json:"y,omitempty"`
	Button *string `json:"button,omitempty"`
	Text   *string `json:"text,omitempty"`
}

type Step struct {
	StepNumber int            `json:"step_number"`
	Action     string         `json:"action"`
	Parameters StepParameters `json:"parameters"`
}

type AutomationFlow struct {
	Steps []Step `json:"steps"`
}

type AutomationApp struct {
	app     fyne.App
	window  fyne.Window
	steps   []Step
	stepList *widget.List
	selectedIndex int
}

func NewAutomationApp() *AutomationApp {
	myApp := app.New()
	myWindow := myApp.NewWindow("自动化流程配置器")
	myWindow.Resize(fyne.Size{Width: 800, Height: 600})

	return &AutomationApp{
		app:           myApp,
		window:        myWindow,
		steps:         []Step{},
		selectedIndex: -1,
	}
}

func (a *AutomationApp) createUI() fyne.CanvasObject {
	// 步骤列表
	a.stepList = widget.NewList(
		func() int {
			return len(a.steps)
		},
		func() fyne.CanvasObject {
			return widget.NewLabel("")
		},
		func(i widget.ListItemID, item fyne.CanvasObject) {
			if i < len(a.steps) {
				step := a.steps[i]
				text := fmt.Sprintf("步骤%d: %s", step.StepNumber, a.getActionDescription(step))
				item.(*widget.Label).SetText(text)
			}
		},
	)
	
	a.stepList.OnSelected = func(id widget.ListItemID) {
		a.selectedIndex = id
	}

	// 按钮
	addBtn := widget.NewButton("添加步骤", a.showAddStepDialog)
	editBtn := widget.NewButton("编辑步骤", a.editSelectedStep)
	deleteBtn := widget.NewButton("删除步骤", a.deleteSelectedStep)
	saveBtn := widget.NewButton("保存配置", a.saveConfiguration)
	loadBtn := widget.NewButton("加载配置", a.loadConfiguration)

	buttonContainer := container.NewHBox(addBtn, editBtn, deleteBtn, saveBtn, loadBtn)

	// 主布局
	content := container.NewBorder(
		nil,
		buttonContainer,
		nil,
		nil,
		a.stepList,
	)

	return content
}

func (a *AutomationApp) getActionDescription(step Step) string {
	switch step.Action {
	case "move_mouse":
		return fmt.Sprintf("移动鼠标到 (%d, %d)", *step.Parameters.X, *step.Parameters.Y)
	case "click_mouse":
		return fmt.Sprintf("鼠标%s键点击", *step.Parameters.Button)
	case "move_and_click":
		return fmt.Sprintf("移动鼠标到 (%d, %d) 并%s键点击", *step.Parameters.X, *step.Parameters.Y, *step.Parameters.Button)
	case "keyboard_input":
		return fmt.Sprintf("键盘输入 \"%s\"", *step.Parameters.Text)
	default:
		return "未知操作"
	}
}

func (a *AutomationApp) showAddStepDialog() {
	actionSelect := widget.NewSelect([]string{
		"move_mouse",
		"click_mouse", 
		"move_and_click",
		"keyboard_input",
	}, nil)
	actionSelect.SetSelected("move_mouse")

	xEntry := widget.NewEntry()
	xEntry.SetText("0")
	yEntry := widget.NewEntry()
	yEntry.SetText("0")
	
	captureBtn := widget.NewButton("📍 捕获坐标", func() {
		a.captureMouseCoordinate(xEntry, yEntry)
	})
	
	buttonSelect := widget.NewSelect([]string{"left", "right", "middle"}, nil)
	buttonSelect.SetSelected("left")
	textEntry := widget.NewEntry()

	form := &widget.Form{
		Items: []*widget.FormItem{
			{Text: "操作类型", Widget: actionSelect},
			{Text: "坐标 (X, Y)", Widget: container.NewVBox(
				container.NewHBox(widget.NewLabel("X:"), xEntry),
				container.NewHBox(widget.NewLabel("Y:"), yEntry),
				captureBtn,
			)},
			{Text: "鼠标按键", Widget: buttonSelect},
			{Text: "输入文本", Widget: textEntry},
		},
	}

	dialog.ShowForm("添加步骤", "确定", "取消", form.Items, func(confirmed bool) {
		if confirmed {
			step := a.createStepFromForm(actionSelect.Selected, xEntry.Text, yEntry.Text, buttonSelect.Selected, textEntry.Text)
			a.addStep(step)
		}
	}, a.window)
}

func (a *AutomationApp) createStepFromForm(action, xText, yText, button, text string) Step {
	step := Step{
		StepNumber: len(a.steps) + 1,
		Action:     action,
		Parameters: StepParameters{},
	}

	if action == "move_mouse" || action == "move_and_click" {
		x, _ := strconv.Atoi(xText)
		y, _ := strconv.Atoi(yText)
		step.Parameters.X = &x
		step.Parameters.Y = &y
	}

	if action == "click_mouse" || action == "move_and_click" {
		step.Parameters.Button = &button
	}

	if action == "keyboard_input" {
		step.Parameters.Text = &text
	}

	return step
}

func (a *AutomationApp) addStep(step Step) {
	a.steps = append(a.steps, step)
	a.stepList.Refresh()
}

func (a *AutomationApp) editSelectedStep() {
	if a.selectedIndex < 0 || a.selectedIndex >= len(a.steps) {
		dialog.ShowInformation("提示", "请先选择要编辑的步骤", a.window)
		return
	}

	step := a.steps[a.selectedIndex]
	
	actionSelect := widget.NewSelect([]string{
		"move_mouse",
		"click_mouse", 
		"move_and_click",
		"keyboard_input",
	}, nil)
	actionSelect.SetSelected(step.Action)

	xEntry := widget.NewEntry()
	yEntry := widget.NewEntry()
	if step.Parameters.X != nil {
		xEntry.SetText(strconv.Itoa(*step.Parameters.X))
	}
	if step.Parameters.Y != nil {
		yEntry.SetText(strconv.Itoa(*step.Parameters.Y))
	}

	captureBtn := widget.NewButton("📍 捕获坐标", func() {
		a.captureMouseCoordinate(xEntry, yEntry)
	})

	buttonSelect := widget.NewSelect([]string{"left", "right", "middle"}, nil)
	if step.Parameters.Button != nil {
		buttonSelect.SetSelected(*step.Parameters.Button)
	}

	textEntry := widget.NewEntry()
	if step.Parameters.Text != nil {
		textEntry.SetText(*step.Parameters.Text)
	}

	form := &widget.Form{
		Items: []*widget.FormItem{
			{Text: "操作类型", Widget: actionSelect},
			{Text: "坐标 (X, Y)", Widget: container.NewVBox(
				container.NewHBox(widget.NewLabel("X:"), xEntry),
				container.NewHBox(widget.NewLabel("Y:"), yEntry),
				captureBtn,
			)},
			{Text: "鼠标按键", Widget: buttonSelect},
			{Text: "输入文本", Widget: textEntry},
		},
	}

	dialog.ShowForm("编辑步骤", "确定", "取消", form.Items, func(confirmed bool) {
		if confirmed {
			newStep := a.createStepFromForm(actionSelect.Selected, xEntry.Text, yEntry.Text, buttonSelect.Selected, textEntry.Text)
			newStep.StepNumber = step.StepNumber
			a.steps[a.selectedIndex] = newStep
			a.stepList.Refresh()
		}
	}, a.window)
}

func (a *AutomationApp) deleteSelectedStep() {
	if a.selectedIndex < 0 || a.selectedIndex >= len(a.steps) {
		dialog.ShowInformation("提示", "请先选择要删除的步骤", a.window)
		return
	}

	dialog.ShowConfirm("确认删除", "确定要删除选中的步骤吗？", func(confirmed bool) {
		if confirmed {
			a.steps = append(a.steps[:a.selectedIndex], a.steps[a.selectedIndex+1:]...)
			// 重新编号
			for i := range a.steps {
				a.steps[i].StepNumber = i + 1
			}
			a.selectedIndex = -1
			a.stepList.Refresh()
		}
	}, a.window)
}

func (a *AutomationApp) saveConfiguration() {
	flow := AutomationFlow{Steps: a.steps}
	data, err := json.MarshalIndent(flow, "", "  ")
	if err != nil {
		dialog.ShowError(err, a.window)
		return
	}

	err = ioutil.WriteFile("automation_flow.json", data, 0644)
	if err != nil {
		dialog.ShowError(err, a.window)
		return
	}

	dialog.ShowInformation("保存成功", "配置已保存到 automation_flow.json", a.window)
}

func (a *AutomationApp) loadConfiguration() {
	data, err := ioutil.ReadFile("automation_flow.json")
	if err != nil {
		dialog.ShowError(err, a.window)
		return
	}

	var flow AutomationFlow
	err = json.Unmarshal(data, &flow)
	if err != nil {
		dialog.ShowError(err, a.window)
		return
	}

	a.steps = flow.Steps
	a.stepList.Refresh()
	dialog.ShowInformation("加载成功", "配置已从 automation_flow.json 加载", a.window)
}

func (a *AutomationApp) captureMouseCoordinate(xEntry, yEntry *widget.Entry) {
	// 显示倒计时提示并开始捕获
	dialog.ShowInformation("坐标捕获", "请在5秒内移动鼠标到目标位置，5秒后自动捕获当前坐标", a.window)
	
	// 5秒倒计时后捕获坐标
	go func() {
		time.Sleep(5 * time.Second)
		
		// 获取当前鼠标坐标
		x, y := robotgo.GetMousePos()
		
		// 更新输入框
		xEntry.SetText(strconv.Itoa(x))
		yEntry.SetText(strconv.Itoa(y))
		
		dialog.ShowInformation("坐标捕获成功", fmt.Sprintf("已捕获坐标: (%d, %d)", x, y), a.window)
	}()
}

func (a *AutomationApp) Run() {
	a.window.SetContent(a.createUI())
	a.window.ShowAndRun()
}

func main() {
	app := NewAutomationApp()
	app.Run()
}